<template>
	<div ref="listScrollWrapRef"  class="wind-scroll-load-list" @scroll="onScrollHandler">
		<slot></slot>
		<div v-if="!isEmpty" ref="listScrollGuardRef" class="list-scroll-grard">
			<div v-if="!finish&&!error" class="is-loading">{{loadingText}}</div>
			<div v-if="finish&&!error" class="is-finish">{{finishText}}</div>
			<div v-if="error" class="is-error" @click="onErrorClick">{{errorText}}</div>
		</div>
		<empty v-if="isEmpty" :message="emptyText"></empty>
	</div>
</template>
<script lang="ts">
/**
 * ScrollLoadList
 * @desc ScrollLoadList 滚动加载
 */
import { defineComponent, ref, onMounted, onUnmounted } from 'vue'
import { useIntersectionObserver } from '@vueuse/core'
import empty from '../empty'
export default defineComponent({
	name: 'w-scroll-load-list',
	components: {
		empty
	},
	props: {
		loading: Boolean,
		loadingText: {
			type: String,
			default: '正在加载'
		},
		finish: Boolean,
		finishText: {
			type: String,
			default: '没有更多了'
		},
		error: Boolean,
		errorText: {
			type: String,
			default: '加载失败'
		},
		immediateCheck: {
			type: Boolean,
			default: true
		},
		isEmpty: Boolean,
		emptyText: {
			type: String,
			default: '筛选无结果'
		}
	},
	emits: ['load', 'update:loading', 'update:error'],
	setup (props, { emit }) {
		const listScrollGuardRef = ref<HTMLElement | null>(null)
		const listScrollWrapRef = ref<HTMLElement | null>(null)
		const scrollTop = ref(0)
		let watchScroll = false
		if (props.immediateCheck) {
			watchScroll = true
		}
		const watchScrollHandler = () => {
			watchScroll = true
			endWatchScroll()
		}
		const startWatchScroll = () => {
			listScrollWrapRef.value?.addEventListener('scroll', watchScrollHandler)
		}
		const endWatchScroll = () => {
			listScrollWrapRef.value?.removeEventListener('scroll', watchScrollHandler)
		}
		const onErrorClick = () => {
			emit('update:error', false)
			emit('load')
		}
		onMounted(() => startWatchScroll())
		onUnmounted(() => endWatchScroll())
		useIntersectionObserver(
			listScrollGuardRef,
			([{ isIntersecting }]) => {
				if (watchScroll && !props.loading && !props.finish && isIntersecting) {
					emit('update:loading', true)
					emit('load')
				}
			}
		)
		const onScrollHandler = (event: Event) => {
			scrollTop.value = (event.target! as HTMLElement).scrollTop
		}
		const setScrollTopDefault = () => {
			listScrollWrapRef.value!.scrollTop = scrollTop.value
		}
		const initScrollTop = () => {
			listScrollWrapRef.value!.scrollTop = 0
		}
		const clearScrollTop = () => {
			scrollTop.value = 0
		}
		return {
			listScrollGuardRef,
			listScrollWrapRef,
			onErrorClick,
			onScrollHandler,
			setScrollTopDefault,
			initScrollTop,
			clearScrollTop
		}
	}
})
</script>
<style lang="scss" scoped>
@import "$assets/stylus/varsty";
.wind-scroll-load-list {
	position: relative;
    display: flex;
    overflow: auto;
    flex: 1;
    flex-flow: row wrap;
    align-content: flex-start;
    column-count: 3;
	box-sizing: border-box;
    .list-scroll-grard {
        width: 100%;
        height: 40px;
        text-align: center;
    }
}
</style>
